package org.easy4j.framework.core.orm;

import org.easy4j.framework.core.annotation.AnnotationUtils;
import org.easy4j.framework.core.orm.annotation.Column;
import org.easy4j.framework.core.orm.annotation.Id;
import org.easy4j.framework.core.orm.annotation.Table;
import org.easy4j.framework.core.util.ReflectUtils;
import org.easy4j.framework.core.util.base.Strings;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author bjliuyong
 * @version 1.0
 * @created date 15-10-23
 */
public class EntityMapping {


    private static Map<String,Mapping> mappings = new HashMap<String, Mapping>();

    public static  Map<String,Mapping> getMappings(){
        return mappings ;
    }

    public static void initMapping(Class entityClass) {

        List<Field> fields = ReflectUtils.findAllField(entityClass);
        List<String> insertableList = new ArrayList<String>() ;
        List<String> updatableList  = new ArrayList<String>() ;

        Mapping mapping = new Mapping(fields.size());

        String idField = null ;
        int count = 0 ,i = 0 ,len = fields.size();

        for( ; i < len ; i++  ){
            Field field = fields.get(i) ;
            int mod = field.getModifiers() ;

            if( Modifier.isPublic(mod) || Modifier.isFinal(mod) || Modifier.isStatic(mod))
                continue;

            Column column = AnnotationUtils.findAnnotation(field,Column.class);

            //设置了忽略该字段
            if( column != null && column.ignore())
                continue;

            String fieldName   = field.getName() ;
            String columnName  = column != null ? column.value() : null ;

            if(columnName == null || columnName.isEmpty() )
                columnName = Strings.humpToUnderLine(fieldName) ;

            Id id = AnnotationUtils.findAnnotation(field,Id.class);

            idField = ( id == null ) ? idField : fieldName ;

            if( column != null  ) {
                if(column.insertable()) insertableList.add(fieldName) ;
                if(column.updatable())   updatableList.add(fieldName) ;
            }

            if(column == null ) {
                insertableList.add(fieldName) ;
                updatableList.add(fieldName) ;
            }

            mapping.put(count++, fieldName, columnName);
        }

        mapping.reset(count ,idField ,insertableList ,updatableList);

        mappings.put(getTableName(entityClass),mapping);
    }

    public static Mapping getMapping(String tableName){
        return mappings.get(tableName);
    }

    public static Mapping getMapping(Class beanType){
        return mappings.get(getTableName(beanType));
    }

    public static String getTableName(Class beanClass){

        Table table = AnnotationUtils.findAnnotation(beanClass, Table.class);
        if(table != null){
            String tableVal = table.value() ;
            return tableVal == null || tableVal.isEmpty()? Strings.humpToUnderLine(beanClass.getSimpleName()) : tableVal;
        } else {
            return Strings.humpToUnderLine(beanClass.getSimpleName());
        }
    }


}
